package cevent.source.cloudcenter.server.service;

import cevent.source.cloudcenter.server.domain.Resources;
import cevent.source.cloudcenter.server.domain.ResourcesExample;
import cevent.source.cloudcenter.server.dto.PageDto;
import cevent.source.cloudcenter.server.dto.ResourcesDto;
import cevent.source.cloudcenter.server.exception.SystemException;
import cevent.source.cloudcenter.server.exception.SystemExceptionCode;
import cevent.source.cloudcenter.server.mapper.ResourcesMapper;
import cevent.source.cloudcenter.server.util.DuplicateUtil;
import cevent.source.cloudcenter.server.util.UUID8Util;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author cevent
 * @description 权限资源管理表服务层
 */
@Service
public class ResourcesService {

    private static final Logger LOG = LoggerFactory.getLogger(ResourcesService.class);
    @Resource
    private ResourcesMapper resourcesMapper;

    //1.无分页列表查询：dto获取domain参数
    public List<ResourcesDto> resourcesDtoList() {
        ResourcesExample resourcesExample = new ResourcesExample();
        resourcesExample.setOrderByClause("uni_id asc");
        List<Resources> resourcesList = resourcesMapper.selectByExample(resourcesExample);
        List<ResourcesDto> resourcesDtoList = new ArrayList<ResourcesDto>();
        for (int i = 0; i < resourcesList.size(); i++) {
            Resources resources = resourcesList.get(i);
            ResourcesDto resourcesDto = new ResourcesDto();
            //复制拷贝(source,target)
            BeanUtils.copyProperties(resources, resourcesDto);
            resourcesDtoList.add(resourcesDto);
        }
        return resourcesDtoList;
    }

    /*2.分页查询：pageDto保存数据
        list数据集合：listPageData
        当前页码：currentPage
        每页行数：size
        总计函数：totalSize
        前端可返回pageDto，无需返回值
     */
    public void getResourcesPageDtoList(PageDto pageDto) {
        //1.分页设置（前端传入当前页和每页行数params），起始页，每页行数size
        PageHelper.startPage(pageDto.getCurrentPage(), pageDto.getSize());

        ResourcesExample resourcesExample = new ResourcesExample();


        List<Resources> resourcesList = resourcesMapper.selectByExample(resourcesExample);
        //2.将mapper查询结果复制到pageInfo
        PageInfo<Resources> pageInfo = new PageInfo<>(resourcesList);
        //3.pageInfo计算处理处理=>后分页的总行数set到pageDto做记录
        pageDto.setTotalSize(pageInfo.getTotal());

        List<ResourcesDto> resourcesDtoList = new ArrayList<>();
        resourcesList.stream().forEach(resources -> {
            ResourcesDto resourcesDto = new ResourcesDto();
            BeanUtils.copyProperties(resources, resourcesDto);
            resourcesDtoList.add(resourcesDto);
        });

        pageDto.setListPageData(resourcesDtoList);

    }

    //3.新增、修改resources，将传入的id转为resources对象本身
    public void save(ResourcesDto resourcesDto) {
        Resources resources = DuplicateUtil.copy(resourcesDto, Resources.class);
        if (StringUtils.isEmpty(resourcesDto.getUniId())) {
            this.insert(resources);
        } else {
            this.update(resources);
        }

    }

    //4.删除模块
    public void delete(String uniId) {
        ResourcesExample resourcesExample = new ResourcesExample();
        resourcesMapper.deleteByPrimaryKey(uniId);
    }

    //5.向外暴露dto，不暴露实体类：插入数据
    private void insert(Resources resources) {
        if(resources.getUniId()==null){
            resources.setUniId(UUID8Util.getShortUUID());
        }
        if(resources.getParentId().isEmpty()){
            resources.setParentId("00000000");

        }
        //不生成短ID，直接读取json的id
        LOG.info("插入的resource：{}", resources);
        resourcesMapper.insert(resources);
    }

    //6.更新模块
    private void update(Resources resources) {
        try {
            Date now = new Date();
            String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(now);
            long time = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(date).getTime();
            int timeInt = (int) (time / 1000);

        } catch (ParseException e) {
            e.printStackTrace();
        }

        resourcesMapper.updateByPrimaryKey(resources);
    }

    //7.批量保存资源
    public ResourcesDto saveJson(String json) {
        ResourcesDto resourcesDto = new ResourcesDto();
        //将json转换为tree树形结构resources对象数组

        List<ResourcesDto> resourcesDtos = null;
        try {
            //转换异常保存
            resourcesDtos = JSON.parseArray(json, ResourcesDto.class);
            LOG.info("传入的resourcesDtos：{}",resourcesDtos);
        } catch (Exception e) {
            e.printStackTrace();
            throw new SystemException(SystemExceptionCode.RESOURCE_INPUT_ERROR);
        }
        //接收转换为List后，遍历提取的每一行数据对象
        List<ResourcesDto> resourcesDtoList = new ArrayList<>();
        //遍历数组
        if (!CollectionUtils.isEmpty(resourcesDtos)) {
            for (ResourcesDto resource : resourcesDtos) {
                LOG.info("转换后的json-obj：{}",resource);
                //数组中，第一个节点的parent为空，根据这个节点，查找所有子节点
                //resource.setParentId("00000000");
                addChildren(resourcesDtoList, resource);
            }
        }
        LOG.info("转换后的resourceList对象：{} ，共{}条", resourcesDtoList, resourcesDtoList.size());
        //插入数据之前清空表，example不加条件，清空表
        resourcesMapper.deleteByExample(null);
        LOG.info("到达全部删除！");
        for (int i = 0; i < resourcesDtoList.size(); i++) {
            //循环插入每条数据
            this.insert(DuplicateUtil.copy(resourcesDtoList.get(i), Resources.class));
        }
        return resourcesDto;
    }

    private void addChildren(List<ResourcesDto> resourcesDtoList, ResourcesDto resourcesDto) {
        //将第一层父节点存入
        resourcesDtoList.add(resourcesDto);
        if (!CollectionUtils.isEmpty(resourcesDto.getChildren())) {
            for (ResourcesDto dto : resourcesDto.getChildren()) {
                //从传入的dto获取父节点id,递归
                dto.setParentId(resourcesDto.getUniId());
                addChildren(resourcesDtoList, dto);
                LOG.info("递归增加的resource-dto：{}", dto);
            }
        }
    }

    //8.获取tree结构resources
    public List<ResourcesDto> getResourcesTree() {

        //1.获取所有资源
        ResourcesExample resourcesExample = new ResourcesExample();
        resourcesExample.setOrderByClause("sort asc");
        List<Resources> resources = resourcesMapper.selectByExample(resourcesExample);
        List<ResourcesDto> resourcesDtoList = DuplicateUtil.copyList(resources, ResourcesDto.class);
        //2.组装tree结构
        List<ResourcesDto> level1 = resourcesDtoList.stream().filter((resource) -> {
            //uniid小于2位，判断为父菜单，遍历查询子菜单
            return resource.getParentId().equals("00000000");
            //递归设置子分类
        }).map((res) -> {
            res.setChildren(getResourcesChildren(res, resourcesDtoList));
            return res;
            //返回的res传入sort排序
        }).sorted((res1, res2) -> {
            return (res1.getSort() == null ? 0
                    : res1.getSort()) - (res2.getSort() == null ? 0 : res2.getSort());
        }).collect(Collectors.toList());
        return level1;
    }

    private List<ResourcesDto> getResourcesChildren(ResourcesDto resourcesDto, List<ResourcesDto> resourcesDtos) {
        //1.过滤菜单
        List<ResourcesDto> resourcesDtoList = resourcesDtos.stream().filter(resource -> {
            //1.1父子资源判断
            return resource.getParentId().equals(resourcesDto.getUniId());
            //1.2递归查询，再次自调用获取子资源列表
        }).map((res) -> {
            res.setChildren(getResourcesChildren(res, resourcesDtos));
            return res;
        }).sorted((res1, res2) -> {
            return (res1.getSort() == null ? 0
                    : res1.getSort()) - (res2.getSort() == null ? 0 : res2.getSort());
        }).collect(Collectors.toList());
        return resourcesDtoList;
    }

    //根据uniId获取resource
    public ResourcesDto getInfo(String uniId){
        Resources resources=resourcesMapper.selectByPrimaryKey(uniId);
        ResourcesDto resourcesDto=DuplicateUtil.copy(resources,ResourcesDto.class);
        return resourcesDto;
    }

    //获取parentId
    public String getParentId(){
        ResourcesExample resourcesExample= new ResourcesExample();
        resourcesExample.setOrderByClause("sort desc");
        List<Resources> resources=resourcesMapper.selectByExample(resourcesExample);
        List<ResourcesDto> resourcesDtos=DuplicateUtil.copyList(resources,ResourcesDto.class);
        //组装过滤
        List<ResourcesDto> resourcesDtoList=resourcesDtos.stream().filter((resource)->{
            return resource.getUniId().length()<=2;
        }).sorted((res1,res2)->{
            Integer res1ID=Integer.parseInt(res1.getUniId());
            Integer res2ID=Integer.parseInt(res2.getUniId());
            //倒序
            return  res2ID-res1ID;
        }).collect(Collectors.toList());
        LOG.info("主菜单对象集合：{}",resourcesDtoList);
        Integer resultInt=Integer.parseInt(resourcesDtoList.get(0).getUniId())+1;
        String result="0"+resultInt;
        return result;
    }

    //拖拽批量保存
    public List<ResourcesDto> updateLevelBatchByUnid(ResourcesDto[] resourcesDtos){
        //1.将传入的数组，转化为dtoList
        List<ResourcesDto> resourcesDtoList= Arrays.asList(resourcesDtos);
        //2.将dtoList复制到domain-List
        List<Resources> resources=DuplicateUtil.copyList(resourcesDtoList,Resources.class);
        //3.循环domain-List
        for(int i=0;i<resources.size();i++){
            Resources resource=resources.get(i);
            //5.批量更新sql
            resourcesMapper.updateByPrimaryKey(resource);
        }
        return resourcesDtoList;
    }

    //批量删除
    public int delBatchResources(String[] uniIds){
        ResourcesExample resourcesExample=new ResourcesExample();
        //将字符串数组转化为arrays
        resourcesExample.createCriteria().andUniIdIn(Arrays.asList(uniIds));
        int flag=resourcesMapper.deleteByExample(resourcesExample);
        return flag;
    }
}
